home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Sprite 1984 - 1993
/
Sprite 1984 - 1993.iso
/
src
/
machserver
/
1.098
/
Include
/
lfsSeg.h
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-09
|
12KB
|
315 lines
/*
* lfsSeg.h --
*
* Declarations of segment writing/cleaning and checkpoint interface
* for LFS. Any module that wishes to write objects to the log
* must register itself with the lfsSeg module and support this
* interface.
*
*
* Copyright 1989 Regents of the University of California
* Permission to use, copy, modify, and distribute this
* software and its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright
* notice appear in all copies. The University of California
* makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without
* express or implied warranty.
*
* $Header: /sprite/src/kernel/lfs/RCS/lfsSeg.h,v 1.9 91/08/08 17:49:41 mendel Exp $ SPRITE (Berkeley)
*/
#ifndef _LFSSEG
#define _LFSSEG
#include <lfsInt.h>
#include <lfsSegLayout.h>
#include <devBlockDevice.h>
/*
* The interface to writing objects to the LFS log is operated using a
* callback interface. Any module may start a segment write by calling
* the LfsSegWriteStart(). The segment write code (in lfsSeg.c) then
* selects a clean segment on disk, initializes a LfsSeg structure for that
* segment, and calls the Layout() subroutine for each module. The Layout()
* adds data blocks and/or summary bytes to the segment. Data blocks
* added to the LfsSeg may use a scatter/gather interface
* consisting of LfsSegElement structures will each SegElement pointing to
* zero or more blocks. Once the segment
* is full or all modules exhaust there need to write, the segment is pushed
* to disk and WriteDone() callback is done for each module writing data.
*
*/
/*
* Data blocks are added to LfsSeg structures in units of LfsSegElement's.
*/
typedef struct LfsSegElement {
Address address; /* The address of the start of the buffer. */
unsigned int lengthInBlocks; /* Length of the buffer in units of file
* system blocks. */
ClientData clientData; /* ClientData usable by the callback
* functions. */
} LfsSegElement;
/*
* LfsSegLogRange describes the position in the segmented log of a segment.
*/
typedef struct LfsSegLogRange {
int current; /* Current segment being accessed */
int prevSeg; /* The segment that was written before the
* current segment. */
int nextSeg; /* Next segment to be written after the
* current segment. */
} LfsSegLogRange;
/*
* The LfsSeg structure is used to describe a segment while objects are being
* added to the segment during writing and removed from the segment during
* cleaning. A segment is divided into two regions: the data block region
* and the summary region. The data block region is may contain zero to
* the segment size (segmentSize in LfsSuperBlockHdr)-1 blocks. The blocks are
* pointed to by an array of LfsSegElement. The summary region is allocated
* in bytes and may grow from one block to an entire segment.
*/
typedef struct LfsSeg {
struct Lfs *lfsPtr; /* The LFS file system this segment belongs.
* Static segment attributes such as number
* blocks can be found in here. */
LfsSegElement *segElementPtr; /* The SegElements making up the data
* region of the segment. */
char *memPtr; /* Segment memory allocated for segment. */
LfsSegLogRange logRange; /* Placement of segment in segmented log. */
int numElements; /* Number of LfsSegElement describing the
* segment. */
int numBlocks; /* Number of blocks in segment. */
int startBlockOffset; /* Starting block offset of this segment. */
int activeBytes; /* Number of active bytes in segment. */
int timeOfLastWrite; /* Time of create of youngest block in seg. */
/*
* Some operations of segments require scanning thru the summary
* and SegElements. The following fields keep the start require
* from this scans.
*/
LfsSegSummary *curSegSummaryPtr; /* Summary of current summary
* block. */
LfsSegSummaryHdr *curSummaryHdrPtr;
/* Current module header being processed. */
int curElement; /* Current LfsSegElement. */
int curBlockOffset; /* The block offset into the segment of the
* end of curElement. */
int curDataBlockLimit; /* Last block offset available in the
* segment. */
char *curSummaryPtr; /* Current offset into the summary region. */
char *curSummaryLimitPtr; /* Current last byte of the summary block
* plus 1. */
/*
* It following fields are used during I/O.
*/
Sync_Semaphore ioMutex; /* Used to sync access to I/O structures
*/
Boolean ioDone; /* TRUE if I/O has finished. */
ReturnStatus ioReturnStatus; /* ReturnStatus of I/O. */
Sync_Condition ioDoneWait; /* Condition to wait for I/O finish. */
DevBlockDeviceRequest bioreq[2]; /* Two request for double buffered I/O.*/
int requestActive; /* Number of IO request active. */
int nextDiskAddress; /* Next disk address to write. */
} LfsSeg;
/*
* The callback interface used by objects wishing to write data to the log is
* defined by the LfsSegIoInterface.
* The exact function each of these layout procedures is
* defined in LfsSeg.c
*/
typedef struct LfsSegIoInterface {
ReturnStatus (*attach) _ARGS_((struct Lfs *lfsPtr, int checkPointSize,
char *checkPointPtr));
/* File system attach routine. Calling sequence:
* attach(lfsPtr, checkPointSize, checkPointPtr)
* Lfs *lfsPtr; -- File system to attach.
* int checkPointSize; Size of checkpoint data
* char *checkPointPtr; Data from last checkpoint
* Attach is called when the file system is attached and is responsible
* for build any in memory data structures needed by the file system.
* The routine returns SUCCESS if things are going ok.
*/
Boolean (*layout) _ARGS_((LfsSeg *segPtr, int flags,
ClientData *clientDataPtr));
/* Segment layout routine. Calling sequence:
* layout(segPtr, cleaning)
* LfsSeg *segPtr; -- Segment to fill in.
* int flags; -- Layout flags.
* ClientData *clientData -- Clientdata for call.
* The module should place all the dirty blocks it can into the log.
* The routine returns TRUE if the module has more data that needs to
* be written to the log.
*/
Boolean (*clean) _ARGS_((LfsSeg *segPtr, int *sizePtr,
int *numCacheBlocksPtr, ClientData *clientDataPtr));
/* Segment cleaning routine. Calling sequence:
* clean(segToCleanPtr, sizePtr)
* LfsSeg *segToCleanPtr; -- Segment to clean.
* int *sizePtr; -- Size in blocks to data to clean.
* Copy the alive blocks from the segToClean into the cache.
*/
Boolean (*checkpoint) _ARGS_((LfsSeg *segPtr, int flags,
char *checkPointPtr, int *checkPointSizePtr,
ClientData *clientDataPtr));
/* Segment checkpoint routine. Calling sequence:
* checkpoint(segPtr, flags, checkPointPtr, checkPointSizePtr)
* LfsSeg *segPtr; -- Segment to fill in.
* int flags; -- Defined in lfsInt.h
* char *checkPointPtr; -- Checkpoint buffer.
* int *checkPointSizePtr -- Out: bytes added to checkpoint area.
* The routine returns TRUE if the module has more data that needs to
* be written to the log.
*/
void (*writeDone) _ARGS_((LfsSeg *segPtr, int flags,
ClientData *clientDataPtr));
/* Segment write finished callback. Calling seq:
* writeDone(segPtr, flags)
* LfsSeg *segPtr; -- Segment finishing write.
* int flags; -- Defined in lfsInt.h.
* Called when a segment write finishes.
*/
ReturnStatus (*detach) _ARGS_((struct Lfs *lfsPtr));
/*
* Detach an LFS file system routine.
*/
int clientDataPerSegSize; /* Size in bytes of client data for each segment
* for this module. */
} LfsSegIoInterface;
/*
* Layout flags.
*/
#define LFS_CLEANING_LAYOUT 0x1000
#define LFS_CHECKPOINT_LAYOUT 0x2000
extern LfsSegIoInterface *lfsSegIoInterfacePtrs[];
/*
* Macros for uses in SegIoInterface callback procedures.
*
* See documentation in the procedure header for the slow version.
*/
/*
* Increase the size of the summary region to bytesNeeded bytes.
* char *
* LfsSegGrowSummary(segPtr, blocks, bytesNeeded)
* LfsSeg *segPtr; -- Segment of interest.
* int blocks; -- Insure this many data blocks remain.
* int bytesNeeded; -- Number of bytes needed in the summary
* region.
*/
#define LfsSegGrowSummary(segPtr, blocks, bytesNeeded) \
LfsSegSlowGrowSummary((segPtr), (blocks), (bytesNeeded), FALSE)
/*
* Return the value of the current pointer into the summary region.
* char *
* LfsSegGetSummaryPtr(segPtr)
* LfsSeg *segPtr; -- Segment of interest.
*/
#define LfsSegGetSummaryPtr(segPtr) ((segPtr)->curSummaryPtr)
/*
* Set the value of the current end of summary region.
* char *
* LfsSegSegSummaryPtr(segPtr, newEndPtr)
* LfsSeg *segPtr; -- Segment of interest.
* char *newEndPtr; -- New value
*/
#define LfsSegSetSummaryPtr(segPtr, newEndPtr) \
((segPtr)->curSummaryPtr = (newEndPtr))
/*
* Return the number of summary bytes left in the summary segment.
* int
* LfsSegSummaryBytesLeft(segPtr)
* LfsSeg *segPtr; -- Segment of interest.
*/
#define LfsSegSummaryBytesLeft(segPtr) \
((segPtr)->curSummaryLimitPtr - (segPtr)->curSummaryPtr)
/*
* Return the number of file system blocks left in the segment.
* int
* LfsSegBlocksLeft(segPtr)
* LfsSeg *segPtr; -- Segment of interest.
*/
#define LfsSegBlocksLeft(segPtr) ((segPtr)->curDataBlockLimit - \
(segPtr)->curBlockOffset)
/*
* Return the disk address of an LfsSegElement
* int
* LfsSegDiskAddress(segPtr, segElementPtr)
* LfsSeg *segPtr; -- Segment of interest.
* LfsSegElement *segElementPtr; -- Segment element of interest
*/
#define LfsSegDiskAddress(segPtr, segElementPtr) \
LfsSegSlowDiskAddress((segPtr), (segElementPtr))
/*
* Add a LfsSegElement to a segment.
* LfsSegElement
* LfsSegAddDataBuffer(segPtr, blocks, bufferPtr, clientData)
* LfsSeg *segPtr; -- Segment of interest.
* int blocks; -- Size of buffer to add in fsBlocks.
* char *bufferPtr; -- Buffer to add.
* ClientData clientData; -- ClientData associated with this field.
*/
#define LfsSegAddDataBuffer(segPtr, blocks, bufferPtr, clientData) \
LfsSegSlowAddDataBuffer((segPtr), (blocks), (bufferPtr), (clientData))
#define LfsSegGetBufferPtr(segPtr) \
((segPtr)->segElementPtr + (segPtr)->curElement)
#define LfsSegSetBufferPtr(segPtr, bufferPtr) \
((segPtr)->curElement = ((bufferPtr) - (segPtr)->segElementPtr))
#define LfsSegSetCurBlockOffset(segPtr, blockOffset) \
((segPtr)->curBlockOffset = blockOffset)
#define LfsSegFetchBytes(segPtr, blockOffset, size) \
((segPtr)->memPtr + LfsSegSize((segPtr)->lfsPtr) - \
LfsBlocksToBytes((segPtr)->lfsPtr, blockOffset))
/* procedures */
extern void LfsSegIoRegister _ARGS_((int moduleType,
LfsSegIoInterface *ioInterfacePtr));
extern char *LfsSegSlowGrowSummary _ARGS_((LfsSeg *segPtr,
int dataBlocksNeeded, int sumBytesNeeded,
Boolean addNewBlock));
extern LfsDiskAddr LfsSegSlowDiskAddress _ARGS_((LfsSeg *segPtr,
LfsSegElement *segElementPtr));
extern LfsSegElement *LfsSegSlowAddDataBuffer _ARGS_((LfsSeg *segPtr,
int blocks, char *bufferPtr, ClientData clientData));
extern ReturnStatus LfsSegAttach _ARGS_((struct Lfs *lfsPtr,
char *checkPointPtr, int checkPointSize));
extern ReturnStatus LfsSegCheckPoint _ARGS_((struct Lfs *lfsPtr,
int flags, char *checkPointPtr,
int *checkPointSizePtr));
extern void LfsSegCheckPointDone _ARGS_((struct Lfs *lfsPtr,
int flags));
extern ReturnStatus LfsSegDetach _ARGS_((struct Lfs *lfsPtr));
#endif /* _LFSSEG */